package com.oa.ht.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.mdp.core.err.BizException;
import com.mdp.core.service.BaseService;
import com.mdp.core.utils.BaseUtils;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.oa.ht.entity.*;
import com.oa.ht.enums.ContractCardEnum;
import com.oa.ht.mapper.ContractCardMapper;
import com.oa.ht.vo.ContractCardAddVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月8日
 */
@Service
public class ContractCardService extends BaseService<ContractCardMapper, ContractCard> {
    static Logger logger = LoggerFactory.getLogger(ContractCardService.class);

    /**
     * 自定义查询，支持多表关联
     *
     * @param page 分页条件
     * @param ew   一定要，并且必须加@Param("ew")注解
     * @param ext  如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
     * @return
     */
    public List<Map<String, Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String, Object> ext) {
        return baseMapper.selectListMapByWhere(page, ew, ext);
    }
    @Lazy
    @Autowired
    private ContractDraftService contractDraftService;

    @Autowired
    private ContractProductService contractProductService;

    @Autowired
    private ContractCbService contractCbService;

    @Autowired
    private ContractConditionService contractConditionService;

    @Autowired
    private ContractProjectService contractProjectService;

    @Autowired
    private CounterpartyService counterpartyService;

    @Autowired
    ContractLogService contractLogService;

    @Autowired
    ContractCommonProcessApprovaService commonProcessApprovaService;

    /**
     * 流程结束,生成合同卡片
     */
    @Transactional
    public void generateContractCard(String draftId) {
        User user = LoginUtils.getCurrentUserInfo();

        //1.根据起草Id查询起草数据
        ContractDraft queryParam = new ContractDraft();
        queryParam.setId(draftId);
        ContractDraft contractDraft = contractDraftService.selectOneObject(queryParam);
        if (StringUtils.isEmpty(contractDraft)) {
            throw new BizException("该流程不存在,归档卡片失败");
        }

        //2.查询相关产品数据
        ContractProduct contractProduct = new ContractProduct();
        contractProduct.setHtId(draftId);
        List<ContractProduct> productList = contractProductService.selectListByWhere(contractProduct);

        //3.查询相关成本数据
        ContractCb contractCb = new ContractCb();
        contractCb.setHtId(draftId);
        List<ContractCb> cbList = contractCbService.selectListByWhere(contractCb);

        //4.查询相关条件数据
        ContractCondition contractCondition = new ContractCondition();
        contractCondition.setHtId(draftId);
        List<ContractCondition> conditionList = contractConditionService.selectListByWhere(contractCondition);

        //5.查询相关条件数据
        ContractProject contractProject = new ContractProject();
        contractProject.setHtId(draftId);
        List<ContractProject> projectList = contractProjectService.selectListByWhere(contractProject);


        //5.生成卡片
        ContractCard contractCard = new ContractCard();
        BeanUtils.copyProperties(contractDraft, contractCard);


        //设置一些特有属性
        contractCard.setHtId(this.createKey("htId"));
        //关联申请流程
        contractCard.setDraftId(draftId);
        //合同总金额
        contractCard.setHtGrossAmount(contractDraft.getHtAmount());
        //签订日期
        contractCard.setHtSignDate(contractDraft.getReqDate());
        //设置卡片状态为未激活
        contractCard.setHtStatus(ContractCardEnum.CARD_INACTIVE.getCode());
        //设置创建时间
        contractCard.setCreateTime(new Date());
        //设置创建用户id
        contractCard.setCreateUserId(user.getUserid());
        //设置创建人
        contractCard.setCreateUserName(user.getUsername());
        //设置负责人
        contractCard.setHtFzUserid(contractDraft.getReqUserId());
        contractCard.setHtFzUsername(contractDraft.getReqUserName());

        String htSn = this.createHtSn(contractCard.getBranchId(), contractCard.getHtType(), contractCard.getCreateTime());
        contractCard.setHtSn(htSn);
        this.insert(contractCard);

        //添加产品，成本，机会
        if (productList != null && productList.size() > 0) {
            productList.stream().forEach(item -> {
                item.setHtId(contractCard.getHtId());
                item.setId(contractProductService.createKey("id"));
            });
            contractProductService.batchInsert(productList);
        }

        if (cbList != null && cbList.size() > 0) {
            cbList.stream().forEach(item -> {
                item.setHtId(contractCard.getHtId());
                item.setCbId(contractCbService.createKey("cbId"));
            });
            contractCbService.batchInsert(cbList);
        }

        if (conditionList != null && conditionList.size() > 0) {
            conditionList.stream().forEach(item -> {
                item.setHtId(contractCard.getHtId());
                item.setConditionId(contractConditionService.createKey("conditionId"));
            });
            contractConditionService.batchInsert(conditionList);
        }

        if (projectList != null && projectList.size() > 0) {
            projectList.stream().forEach(item -> {
                item.setHtId(contractCard.getHtId());
                item.setId(contractProjectService.createKey("id"));
            });
            contractProjectService.batchInsert(projectList);
        }
        contractLogService.addLog(contractCard.getHtId(), user.getUserid(), user.getUsername(), "创建合同 " + contractCard.getHtId() + " " + contractCard.getHtName());
    }

    private String createHtSn(String branchId, String htType, Date htDate) {
        String htSn = branchId.toUpperCase().substring(0, 4);
        Calendar calendar = Calendar.getInstance();
        if (htDate != null) {
            calendar.setTime(htDate);
        }
        htSn = htSn + "-" + calendar.get(Calendar.YEAR) + calendar.get(Calendar.MONTH) + calendar.get(Calendar.DAY_OF_MONTH);
        if (htType == null) {
            htSn = htSn + "-00";
        } else {
            htSn = htSn + "-" + htType;
        }
        ContractCard c = new ContractCard();
        c.setBranchId(branchId);
        long count = this.countByWhere(c);
        htSn = htSn + "-" + (count + 1);
        return htSn;

    }

    /**
     * 查询合同卡片关联的数据
     *
     * @param contractCardList
     */
    public void selectLinkData(List<Map<String, Object>> contractCardList) {

        if (CollectionUtils.isEmpty(contractCardList)) return;

        //合同id列表
        List<String> htIds = Lists.newArrayList();
        htIds = contractCardList.stream().map(item -> (String) item.get("htId")).collect(Collectors.toList());


        Map<String, Object> query = new HashMap<>();

        query.put("htIds", htIds);
        query.put("isThirdParty", "0");

        //1.关联成本
        List<ContractCb> cbList = contractCbService.selectCbByIds(query);

        //2.关联产品
        List<ContractProduct> productList = contractProductService.selectProByIds(query);

        //3.关联机会
        List<ContractCondition> conditionList = contractConditionService.selectConditionByIds(query);

        //关联项目
        List<ContractProject> projectList = contractProjectService.selectProjectByIds(query);

        //组装数据
        Multimap<String, ContractCb> cbMultimap = ArrayListMultimap.create();
        cbList.stream().forEach(item -> cbMultimap.put(item.getHtId(), item));

        Multimap<String, ContractProduct> productMultimap = ArrayListMultimap.create();
        productList.stream().forEach(item -> productMultimap.put(item.getHtId(), item));

        Multimap<String, ContractCondition> conditionMultimap = ArrayListMultimap.create();
        conditionList.stream().forEach(item -> conditionMultimap.put(item.getHtId(), item));

        Multimap<String, ContractProject> projectMultimap = ArrayListMultimap.create();
        projectList.stream().forEach(item -> projectMultimap.put(item.getHtId(), item));

        contractCardList.stream().forEach(item -> {
            List<ContractCb> cbList1 = (List<ContractCb>) cbMultimap.get((String) item.get("htId"));
            item.put("cbList", cbList1);

            List<ContractProduct> productList1 = (List<ContractProduct>) productMultimap.get((String) item.get("htId"));
            item.put("productList", productList1);

            List<ContractCondition> conditionList1 = (List<ContractCondition>) conditionMultimap.get((String) item.get("htId"));
            item.put("conditionList", conditionList1);

            List<ContractProject> projectList1 = (List<ContractProject>) projectMultimap.get((String) item.get("htId"));
            item.put("projectList", projectList1);
        });
    }

    /**
     * 计算合同的各项数据金额
     *
     * @return
     */
    public Map<String, Object> computeAmount() {
        Map<String, Object> result = baseMapper.computeAmount(null);
        return result;
    }

    /**
     * 添加合同卡片
     *
     * @param contractCardAddVo
     */
    public void insertContractCard(ContractCardAddVo contractCardAddVo) {

    }


    public void updateContractCardKaiPiaoAmount(String htId) {
        baseMapper.updateContractCardKaiPiaoAmount(htId);
    }

    public void updateContractCardShouPiaoAmount(String htId) {
        baseMapper.updateContractCardShouPiaoAmount(htId);
    }

    public void updateContractCardCbAmount(String htId) {
        baseMapper.updateContractCardCbAmount(htId);
    }

    /**
     * 修改合同卡片
     *
     * @param contractCardAddVo
     */
    @Transactional
    public void updateContractCard(ContractCardAddVo contractCardAddVo) {
        String htId = contractCardAddVo.getHtId();

        //1.修改卡片主表
        this.updateByPk(contractCardAddVo);
        //4.添加操作记录
        User user = LoginUtils.getCurrentUserInfo();
        contractLogService.addLog(contractCardAddVo.getHtId(), user.getUserid(), user.getUsername(), "修改合同 " + contractCardAddVo.getHtId() + " " + contractCardAddVo.getHtName());


    }

    //获取图表数据
    public Map<String, Object> getChartData(IPage page, QueryWrapper ew, Map<String, Object> contractCard) {
        //合同
        List<Map<String, Object>> maps = this.selectListMapByWhere(page, ew, contractCard);
        //客户
        List<Map<String, Object>> counterpartys = counterpartyService.selectListMapByWhere(page, ew, contractCard);
        //合同金额
        BigDecimal contractMoney = new BigDecimal(0.00);

        //合同数量
        Integer contractNum = maps.size();
        //收入合同
        List<Integer> incomeContracts = new ArrayList<>();
        //支出合同
        List<Integer> expenditureContracts = new ArrayList<>();
        //应收账款
        List<BigDecimal> receivables = new ArrayList<>();
        //应付账款
        List<BigDecimal> accountsPayables = new ArrayList<>();
        //客户数量
        Integer clientNum = counterpartys.size();
        //合同状态分析
        List<Map<String, Object>> contratStatus = new ArrayList<>();
        //客户分布
        List<Map<String, Object>> distribution = new ArrayList<>();
        Map<String, Object> distributionMap = new HashMap<>();

        Map<String, Object> contratStatusMap = new HashMap<>();
        contratStatusMap.put("1", 0);
        contratStatusMap.put("2", 0);
        contratStatusMap.put("3", 0);
        contratStatusMap.put("4", 0);
        contratStatusMap.put("5", 0);
        contratStatusMap.put("6", 0);
        contratStatusMap.put("7", 0);

        for (int i = 0; i < 12; i++) {
            incomeContracts.add(0);
            expenditureContracts.add(0);
            receivables.add(new BigDecimal(0.0));
            accountsPayables.add(new BigDecimal(0.0));
        }


        for (int i = 0; i < maps.size(); i++) {
            Map<String, Object> item = maps.get(i);
            String htParentType = (String) item.get("htParentType");
            String htStatus = (String) item.get("htStatus");
            BigDecimal b = new BigDecimal(0);
            if (item.get("htGrossAmount") != null) {
                b = (BigDecimal) item.get("htGrossAmount");
            }
            contractMoney = contractMoney.add(b);
            BigDecimal htReceivableAmount = (BigDecimal) item.get("htReceivableAmount");
            BigDecimal htPayableAmount = (BigDecimal) item.get("htPayableAmount");
            Date createTime = (Date) item.get("createTime");
            int month = createTime.getMonth();
            //销售类 - 收入合同
            if (htParentType != null && htParentType.equals("1")) {
                Integer num = incomeContracts.get(month);
                incomeContracts.set(month, num + 1);
            }
            //采购类 - 支出合同
            if (htParentType != null && htParentType.equals("2")) {

                Integer num = expenditureContracts.get(month);
                expenditureContracts.set(month, num + 1);
            }
            //合同状态
            if (htStatus != null) {
                Integer num = (Integer) contratStatusMap.get(htStatus);
                if (num != null) {
                    contratStatusMap.put(htStatus, ++num);
                }
            }
            //应收账款
            if (htReceivableAmount != null) {
                BigDecimal num = receivables.get(month);
                num = htReceivableAmount.add(num);
                receivables.set(month, num);
            }
            //应付账款
            if (htPayableAmount != null) {
                BigDecimal num = accountsPayables.get(month);
                num = htPayableAmount.add(num);
                accountsPayables.set(month, num);
            }

        }
        for (int i = 1; i <= 7; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("value", contratStatusMap.get(i + ""));
            if (i == 1) {
                map.put("name", "解除");
            }
            if (i == 2) {
                map.put("name", "终止");
            }
            if (i == 3) {
                map.put("name", "暂停");
            }
            if (i == 4) {
                map.put("name", "未激活");
            }
            if (i == 5) {
                map.put("name", "履行中");
            }
            if (i == 6) {
                map.put("name", "已拆分");
            }
            if (i == 7) {
                map.put("name", "已完成");
            }
            contratStatus.add(map);
        }
        for (int i = 0; i < counterpartys.size(); i++) {
            Map<String, Object> map = counterpartys.get(i);
            String cpProvince = (String) map.get("cpProvince");
            Integer d = (Integer) distributionMap.get(cpProvince);
            if (d == null) {
                distributionMap.put(cpProvince, 1);
            } else {
                distributionMap.put(cpProvince, d + 1);
            }
        }
        for (String key : distributionMap.keySet()) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", key);
            map.put("value", distributionMap.get(key));
            distribution.add(map);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("contractMoney", contractMoney);
        result.put("clientNum", clientNum);
        result.put("contractNum", contractNum);
        result.put("contratStatus", contratStatus);
        result.put("distribution", distribution);
        result.put("incomeContracts", incomeContracts);
        result.put("expenditureContracts", expenditureContracts);
        result.put("receivables", receivables);
        result.put("accountsPayables", accountsPayables);
        return result;
    }

    public Map<String, Object> getStatisticalStatement(Map<String, Object> contractCard) {
        /* 变量声明区 */
        Map<String, Object> result = new HashMap<>();
        //本年合同数量
        Integer contractNum = 0;
        //本年付款金额
        BigDecimal paymentAmount = new BigDecimal(0);
        //本年收款金额
        BigDecimal receivableAmount = new BigDecimal(0);
        //应收金额
        List<BigDecimal> receivables = new ArrayList<>();
        //应付金额
        List<BigDecimal> accountsPayables = new ArrayList<>();
        //收入合同金额
        List<BigDecimal> incomeContractMoneys = new ArrayList<>();
        //支出合同金额
        List<BigDecimal> expenditureContractMoneys = new ArrayList<>();
        //合同状态分析
        List<Map<String, Object>> contratStatus = new ArrayList<>();
        //合同类型统计
        List<Map<String, Object>> contractTypes = new ArrayList<>();

        //开票
        //销售开票合同金额
        List<BigDecimal> marketContractInvoiceaMount = new ArrayList<>();
        //采购开票合同金额
        List<BigDecimal> purchaseContractInvoiceaMount = new ArrayList<>();
        //其他开票合同金额
        List<BigDecimal> otherContractInvoiceaMount = new ArrayList<>();


        //实际收款
        //销售合同实际收款
        List<BigDecimal> marketContractActualPayment = new ArrayList<>();
        //采购合同实际收款
        List<BigDecimal> purchaseContractActualPayment = new ArrayList<>();
        //其他合同实际收款
        List<BigDecimal> otherContractActualPayment = new ArrayList<>();

        //实际付款
        //销售合同实际付款
        List<BigDecimal> marketContractShiJiFuKuan = new ArrayList<>();
        //采购合同实际付款
        List<BigDecimal> purchaseContractShiJiFuKuan = new ArrayList<>();
        //其他合同实际付款
        List<BigDecimal> otherContractShiJiFuKuan = new ArrayList<>();


        /*    初始化区  */
        Map<String, Object> contratStatusMap = new HashMap<>();
        for (int i = 1; i <= 7; i++) {
            contratStatusMap.put(i + "", 0);
        }
        Map<String, Object> contratTypeMap = new HashMap<>();
        for (int i = 1; i <= 3; i++) {
            contratTypeMap.put(i + "", 0);
        }
        for (int i = 0; i < 12; i++) {
            incomeContractMoneys.add(new BigDecimal((0)));
            expenditureContractMoneys.add(new BigDecimal((0)));
            marketContractInvoiceaMount.add(new BigDecimal((0)));
            purchaseContractInvoiceaMount.add(new BigDecimal((0)));
            otherContractInvoiceaMount.add(new BigDecimal((0)));
            marketContractActualPayment.add(new BigDecimal((0)));
            purchaseContractActualPayment.add(new BigDecimal((0)));
            otherContractActualPayment.add(new BigDecimal((0)));

            marketContractShiJiFuKuan.add(new BigDecimal((0)));
            purchaseContractShiJiFuKuan.add(new BigDecimal((0)));
            otherContractShiJiFuKuan.add(new BigDecimal((0)));
        }

        List<Map<String, Object>> contractCards = baseMapper.selectContractCardByThisYear(contractCard);
        contractNum = contractCards.size();

        /* 数据处理区 */
        for (int i = 0; i < 12; i++) {
            receivables.add(new BigDecimal(0.0));
            accountsPayables.add(new BigDecimal(0.0));
            incomeContractMoneys.add(new BigDecimal(0.0));
            expenditureContractMoneys.add(new BigDecimal(0.0));
        }
        for (int i = 0; i < contractCards.size(); i++) {

            Date createTime = (Date) contractCards.get(i).get("createTime");
            int month = createTime.getMonth();

            //应收金额
            BigDecimal htReceivableAmount = (BigDecimal) contractCards.get(i).get("htReceivableAmount");
            //应付金额
            BigDecimal htPayableAmount = (BigDecimal) contractCards.get(i).get("htPayableAmount");
            //合同类型
            String htParentType = (String) contractCards.get(i).get("htParentType");
            //合同状态
            String htStatus = (String) contractCards.get(i).get("htStatus");
            //开票金额
            BigDecimal htKaiPiaoAmount = (BigDecimal) contractCards.get(i).get("htKaiPiaoAmount");
            //实际收款
            BigDecimal htReceivedAmount = (BigDecimal) contractCards.get(i).get("htReceivedAmount");
            //实际付款
            BigDecimal htPayedAmount = (BigDecimal) contractCards.get(i).get("htPayedAmount");


            //本年付款金额
            if (htPayedAmount != null) {
                paymentAmount = htPayedAmount.add(paymentAmount);
            }
            //本年收款金额
            if (htReceivedAmount != null) {
                receivableAmount = htReceivedAmount.add(receivableAmount);
            }
            //应收金额
            if (htReceivableAmount != null) {
                BigDecimal bigDecimal = receivables.get(month);
                BigDecimal num = bigDecimal.add(htReceivableAmount);
                receivables.set(month, num);
            }
            //应付金额
            if (htPayableAmount != null) {
                BigDecimal bigDecimal = accountsPayables.get(month);
                BigDecimal num = bigDecimal.add(htPayableAmount);
                accountsPayables.set(month, num);
            }
            //收入合同金额
            if (htParentType != null && htParentType.equals("1")) {
                if (htReceivableAmount != null) {
                    BigDecimal bigDecimal = incomeContractMoneys.get(month);
                    BigDecimal num = bigDecimal.add(htReceivableAmount);
                    incomeContractMoneys.set(month, num);
                }

            }
            //支出合同金额
            if (htParentType != null && htParentType.equals("2")) {
                if (htPayableAmount != null) {
                    BigDecimal bigDecimal = expenditureContractMoneys.get(month);
                    BigDecimal num = bigDecimal.add(htPayableAmount);
                    expenditureContractMoneys.set(month, num);
                }
            }
            //合同状态
            if (htStatus != null) {
                Integer num = (Integer) contratStatusMap.get(htStatus);
                if (num != null) {
                    contratStatusMap.put(htStatus, ++num);
                }
            }
            //合同类型
            if (htParentType != null) {
                Integer num = (Integer) contratTypeMap.get(htParentType);

                if (num != null) {
                    contratTypeMap.put(htParentType, ++num);
                }
            }
            //开票合同金额
            if (htParentType != null && htKaiPiaoAmount != null) {
                //销售开票合同金额
                if (htParentType.equals("1")) {
                    BigDecimal bigDecimal = marketContractInvoiceaMount.get(month);
                    BigDecimal num = bigDecimal.add(htKaiPiaoAmount);
                    marketContractInvoiceaMount.set(month, num);
                }
                //采购开票合同金额
                if (htParentType.equals("2")) {
                    BigDecimal bigDecimal = purchaseContractInvoiceaMount.get(month);
                    BigDecimal num = bigDecimal.add(htKaiPiaoAmount);
                    purchaseContractInvoiceaMount.set(month, num);
                }
                //其他开票合同金额
                if (htParentType.equals("3")) {
                    BigDecimal bigDecimal = otherContractInvoiceaMount.get(month);
                    BigDecimal num = bigDecimal.add(htKaiPiaoAmount);
                    otherContractInvoiceaMount.set(month, num);
                }
            }
            //实际收款
            if (htParentType != null && htReceivedAmount != null) {
                //销售实际收款
                if (htParentType.equals("1")) {
                    BigDecimal bigDecimal = marketContractActualPayment.get(month);
                    BigDecimal num = bigDecimal.add(htReceivedAmount);
                    marketContractActualPayment.set(month, num);
                }
                //采购实际收款
                if (htParentType.equals("2")) {
                    BigDecimal bigDecimal = purchaseContractActualPayment.get(month);
                    BigDecimal num = bigDecimal.add(htReceivedAmount);
                    purchaseContractActualPayment.set(month, num);
                }
                //其他实际收款
                if (htParentType.equals("3")) {
                    BigDecimal bigDecimal = otherContractActualPayment.get(month);
                    BigDecimal num = bigDecimal.add(htReceivedAmount);
                    otherContractActualPayment.set(month, num);
                }
            }
            //实际付款
            if (htParentType != null && htPayedAmount != null) {
                //销售实际付款
                if (htParentType.equals("1")) {
                    BigDecimal bigDecimal = marketContractShiJiFuKuan.get(month);
                    BigDecimal num = bigDecimal.add(htPayedAmount);
                    marketContractShiJiFuKuan.set(month, num);
                }
                //采购实际付款
                if (htParentType.equals("2")) {
                    BigDecimal bigDecimal = purchaseContractShiJiFuKuan.get(month);
                    BigDecimal num = bigDecimal.add(htPayedAmount);
                    purchaseContractShiJiFuKuan.set(month, num);
                }
                //其他实际付款
                if (htParentType.equals("3")) {
                    BigDecimal bigDecimal = otherContractShiJiFuKuan.get(month);
                    BigDecimal num = bigDecimal.add(htPayedAmount);
                    otherContractShiJiFuKuan.set(month, num);
                }
            }
        }
        //组合合同状态
        for (int i = 1; i <= 7; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("value", contratStatusMap.get(i + ""));
            if (i == 1) {
                map.put("name", "解除");
            }
            if (i == 2) {
                map.put("name", "终止");
            }
            if (i == 3) {
                map.put("name", "暂停");
            }
            if (i == 4) {
                map.put("name", "未激活");
            }
            if (i == 5) {
                map.put("name", "履行中");
            }
            if (i == 6) {
                map.put("name", "已拆分");
            }
            if (i == 7) {
                map.put("name", "已完成");
            }
            contratStatus.add(map);
        }
        //组合合同类型
        for (int i = 1; i <= 3; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("value", contratTypeMap.get(i + ""));
            if (i == 1) {
                map.put("name", "销售合同");
            }
            if (i == 2) {
                map.put("name", "采购合同");
            }
            if (i == 3) {
                map.put("name", "其他");
            }
            contractTypes.add(map);
        }
        result.put("contractNum", contractNum);
        result.put("paymentAmount", paymentAmount);
        result.put("receivableAmount", receivableAmount);
        result.put("receivables", receivables);
        result.put("accountsPayables", accountsPayables);
        result.put("incomeContractMoneys", incomeContractMoneys);
        result.put("expenditureContractMoneys", expenditureContractMoneys);
        result.put("contratStatus", contratStatus);
        result.put("contractTypes", contractTypes);
        result.put("marketContractInvoiceaMount", marketContractInvoiceaMount);
        result.put("purchaseContractInvoiceaMount", purchaseContractInvoiceaMount);
        result.put("otherContractInvoiceaMount", otherContractInvoiceaMount);
        result.put("marketContractActualPayment", marketContractActualPayment);
        result.put("purchaseContractActualPayment", purchaseContractActualPayment);
        result.put("otherContractActualPayment", otherContractActualPayment);

        result.put("marketContractShiJiFuKuan", marketContractShiJiFuKuan);
        result.put("purchaseContractShiJiFuKuan", purchaseContractShiJiFuKuan);
        result.put("otherContractShiJiFuKuan", otherContractShiJiFuKuan);

        return result;
    }


    /** 请在此类添加自定义函数 */

    /**
     * 流程审批过程中回调该接口，更新业务数据
     * 如果发起流程时上送了restUrl，则无论流程中是否配置了监听器都会在流程发生以下事件时推送数据过来
     * eventName: PROCESS_STARTED 流程启动完成 全局
     * PROCESS_COMPLETED 流程正常结束 全局
     * PROCESS_CANCELLED 流程删除 全局
     * create 人工任务启动
     * complete 人工任务完成
     * assignment 人工任务分配给了具体的人
     * delete 人工任务被删除
     * TASK_COMPLETED_FORM_DATA_UPDATE 人工任务提交完成后，智能表单数据更新
     * <p>
     * 其中 create/complete/assignment/delete事件是需要在模型中人工节点上配置了委托代理表达式 ${taskBizCallListener}才会推送过来。
     * 在人工任务节点上配置 任务监听器  建议事件为 complete,其它assignment/create/complete/delete也可以，一般建议在complete,委托代理表达式 ${taskBizCallListener}
     *
     * @param flowVars {flowBranchId,agree,procInstId,startUserid,assignee,actId,taskName,mainTitle,branchId,bizKey,commentMsg,eventName,modelKey} 等
     * @return 如果tips.isOk==false，将影响流程提交
     **/
    @Transactional
    public void processApprova(Map<String, Object> flowVars) {
        String eventName = (String) flowVars.get("eventName");
        String agree = (String) flowVars.get("agree");
        String branchId = (String) flowVars.get("branchId");
        String htId = (String) flowVars.get("htId");//合同编号
        String bizKey = (String) flowVars.get("bizKey");
        if ("contract_signing_process_approva".equals(bizKey)) {
        } else if ("contract_change_process_approva".equals(bizKey)) {
            if (!flowVars.containsKey("data")) {
                throw new BizException("请上送合同相关字段信息到data参数中");
            }
        } else {
            throw new BizException("不支持的业务,请上送业务编码【bizKey】参数");
        }

        if ("complete".equals(eventName)) {
            if ("1".equals(agree)) {
                this.updateFlowStateByProcInst(null, flowVars);
            } else {
                this.updateFlowStateByProcInst(null, flowVars);
            }
        } else {
            if ("PROCESS_STARTED".equals(eventName)) {
                Map<String, Object> bizQuery = new HashMap<>();
                bizQuery.put("id", htId);
                if (StringUtils.isEmpty(htId)) {
                    throw new BizException("请上送合同编号-htId");
                }
                if (StringUtils.isEmpty(branchId)) {
                    throw new BizException("请上送branchId");
                }
                ContractCard contractCard = this.selectOneObject(new ContractCard(htId));
                if (contractCard == null) {
                    throw new BizException("没有找到对应合同,合同编号为【" + htId + "】");
                } else {
                    if ("1".equals(contractCard.getBizFlowState())) {
                        throw new BizException("该合同正在审批中，不能再发起审批");
                    }
                }

                flowVars.put("id", this.createKey("id"));
                flowVars.put("contractId", htId);
                flowVars.put("contractName", contractCard.getHtName());
                ContractCard update = new ContractCard();
                update.setHtId(contractCard.getHtId());
                update.setBizFlowState("1");
                update.setBizProcInstId((String) flowVars.get("procInstId"));
                this.updateSomeFieldByPk(update);
                flowVars.put("flowState", "1");
                flowVars.put("flowLastTime", new Date());
                commonProcessApprovaService.insert(BaseUtils.fromMap(flowVars, ContractCommonProcessApprova.class));
                if ("contract_signing_process_approva".equals(bizKey)) {
                    this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同签订审核流程启动");
                }
                if ("contract_change_process_approva".equals(bizKey)) {
                    this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同变更审核流程启动");
                }
                //this.updateFlowStateByProcInst("1", flowVars);
            } else if ("PROCESS_COMPLETED".equals(eventName)) {
                //流程表、订单表更新
                flowVars.put("flowEndTime", 1);//传入任意数值，表示flowEndTime需要修改
                if ("1".equals(agree)) {
                    if ("contract_signing_process_approva".equals(bizKey)) {
                        flowVars.put("htStatus", "5");
                        this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同签订生效审批通过");
                    }
                    if ("contract_change_process_approva".equals(bizKey)) {
                        Map<String, Object> data = (Map<String, Object>) flowVars.get("data");
                        ContractCard contractCard = BaseUtils.fromMap(data, ContractCard.class);
                        this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), (String) flowVars.get("diffMsg"));
                        this.updateSomeFieldByPk(contractCard);
                    }
                    this.updateFlowStateByProcInst("2", flowVars);
                } else {
                    if ("contract_signing_process_approva".equals(bizKey)) {
                        this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同签订审核流程已被拒绝");
                    }
                    if ("contract_change_process_approva".equals(bizKey)) {
                        this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同变更审核流程已被拒绝");
                    }
                    this.updateFlowStateByProcInst("3", flowVars);
                }
            } else if ("PROCESS_CANCELLED".equals(eventName)) {
                //cancel为流程取消状态
                flowVars.put("flowEndTime", 1);//传入任意数值，表示flowEndTime需要修改
                if ("contract_signing_process_approva".equals(bizKey)) {
                    this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同签订审核流程取消");
                }
                if ("contract_change_process_approva".equals(bizKey)) {
                    this.contractLogService.addLog(htId, (String) flowVars.get("startUserid"), (String) flowVars.get("startUsername"), "合同变更审核流程取消");
                }

                this.updateFlowStateByProcInst("4", flowVars);
            }
        }

    }

    /**
     * 0初始1审批中2审批通过3审批不通过4流程取消或者删除
     *
     * @param flowState 0初始1审批中2审批通过3审批不通过4流程取消或者删除
     * @param flowVars
     */
    public void updateFlowStateByProcInst(String flowState, Map<String, Object> flowVars) {
        flowVars.put("flowState", flowState);
        flowVars.put("bizFlowState", flowState);
        if ("1".equals(flowState)) {
            flowVars.put("bizProcInstId", flowVars.get("procInstId"));
        }
        commonProcessApprovaService.contractCardUpdateProcessApprova(flowVars);
    }

    public void updateContractCardHtPayedAmount(String htId) {
        baseMapper.updateContractCardHtPayedAmount(htId);
    }

    public void updateContractCardHtReceivedAmount(String htId) {
        baseMapper.updateContractCardHtReceivedAmount(htId);
    }
}

